package nl.rug.ml.dobbelen.game;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import nl.rug.ml.dobbelen.learning.DobbelenState;
import nl.rug.ml.dobbelen.learning.DobbelenUtils;

/**
 * Define the score of dices.
 * 
 * @author Do Bich Ngoc (bichngocdo89@gmail.com)
 * 
 */
public class DobbelenDiceScorer {

	public static int calculateScore(List<Dice> dices) {
		int[] scoreHistogram = DobbelenUtils.dicesToHistogram(dices);
		int score = 0;

		// Straight
		if (scoreHistogram[0] == 1 && scoreHistogram[1] == 1 && scoreHistogram[2] == 1 && scoreHistogram[3] == 1 && scoreHistogram[4] == 1 && scoreHistogram[5] == 1) {
			return 1500;
		}

		// Triplet, must be obtained in one throw
		for (int i = 0; i < scoreHistogram.length; i++) {
			if (scoreHistogram[i] >= 3) {
				Map<Integer, Integer> turnCount = new HashMap<Integer, Integer>();
				for (Dice dice : dices) {
					if (dice.getValue() == i + 1) {
						int turn = dice.getTurn();
						if (turnCount.containsKey(turn)) {
							int count = turnCount.get(turn);
							turnCount.put(turn, ++count);
						}
						else {
							turnCount.put(turn, 1);
						}
					}
				}

				for (Entry<Integer, Integer> entry : turnCount.entrySet()) {
					int count = entry.getValue();
					while (count >= 3) {
						if (i != 0) {
							score += 100 * (i + 1);
						}
						else {
							score += 1000;
						}
						count -= 3;
						scoreHistogram[i] -= 3;
					}
				}
			}
		}

		// Calculate score for 1 and 5 faces
		score += scoreHistogram[0] * 100 + scoreHistogram[4] * 50;

		return score;
	}

	public static int calculateScore(DobbelenState state) {
		int score = 0;
		int[] extendedHistogram = state.getExtendedHistogram();
		int[] index = state.getIndex();

		// Straight
		boolean hasStraight = true;
		for (int i = 0; i < index.length - 1; i++) {
			hasStraight = hasStraight & (extendedHistogram[index[i + 1] - 1] == 1);
		}
		if (hasStraight) {
			return 1500;
		}

		for (int i = 0; i < index.length - 1; i++) {
			for (int j = index[i]; j < index[i + 1]; j++) {
				if (j != index[i + 1] - 1) {
					// Triplet
					if (i == 0) {
						score += (extendedHistogram[j] / 3) * 1000;
					}
					else {
						score += (extendedHistogram[j] / 3) * (i + 1) * 100;
					}
				}
				else if (i == 0) {
					// Face 1, non triplet
					score += extendedHistogram[j] * 100;
				}
				else if (i == 4) {
					// Face 5, non triplet
					score += extendedHistogram[j] * 50;
				}
			}
		}
		return score;
	}

}
